package com.school.admin.common.filter;

import cn.hutool.core.io.IoUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.school.admin.common.annotation.IgnoreEncryption;
import com.school.admin.common.config.SystemConfig;
import com.school.admin.common.utils.RsaUtils;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Type;
import java.nio.charset.StandardCharsets;
import java.util.Objects;

/**
 * @author ：zzz
 * @date ：Created in 2021/3/28 22:09
 * @description：跨域
 * @modified By：
 * @version: $
 */
@RestControllerAdvice
public class RequestBodyAdviceFilter implements RequestBodyAdvice {
    @Override
    public boolean supports(MethodParameter methodParameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
        return methodParameter.getParameterAnnotation(RequestBody.class) != null;
    }

    @Override
    public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) throws IOException {

        boolean ignoreEncryption = Objects.requireNonNull(parameter.getMethod()).isAnnotationPresent(IgnoreEncryption.class);

        InputStream body = inputMessage.getBody();
        String s = IoUtil.read(body).toString();
        JSONObject jsonObject = JSONUtil.parseObj(s);
        //是否忽略加密
        if (SystemConfig.isParameterEncryption && !ignoreEncryption){
            String postData = (String) jsonObject.get("postData");
            String decrypt = RsaUtils.decrypt(postData);


            return new HttpInputMessage() {
                @Override
                public HttpHeaders getHeaders() {
                    return inputMessage.getHeaders();
                }

                @Override
                public InputStream getBody() throws IOException {
                    return new ByteArrayInputStream(decrypt.getBytes(StandardCharsets.UTF_8));
                }
            };
        }

        return new HttpInputMessage() {
            @Override
            public InputStream getBody() throws IOException {
                return new ByteArrayInputStream(s.getBytes(StandardCharsets.UTF_8));
            }

            @Override
            public HttpHeaders getHeaders() {
                return inputMessage.getHeaders();
            }
        };
    }

    @Override
    public Object afterBodyRead(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
        return body;
    }

    @Override
    public Object handleEmptyBody(Object body, HttpInputMessage inputMessage, MethodParameter parameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
        return body;
    }
}
